package com.zhai.scan;

import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 *
 */
public class DubboScanReflect {

    private static final String RESOURCE_PATTERN = "/**/*.class";

    /**
     * 根据扫描路径获取所有的类信息
     *
     * @param rpcScanPath
     * @return
     */
    public static List<Class> getScanClass(String rpcScanPath) {
        if (StringUtils.isEmpty(rpcScanPath)) {
            return null;
        }
        String[] arrays = rpcScanPath.split(",");
        if (arrays.length == 0) {
            return null;
        }
        List<Class> allScanClazz = new ArrayList<>();
        for (int i = 0; i < arrays.length; i++) {
            String classPath = arrays[i];
            List<Class> pathClazzList = getPathClass(classPath);
            allScanClazz.addAll(pathClazzList);
        }
        return allScanClazz;
    }

    /**
     * @param basePackage
     * @return
     */
    public static List<Class> getPathClass(String basePackage) {
        if (StringUtils.isEmpty(basePackage)) {
            return null;
        }
        List<Class> classList = new ArrayList<>();
        //spring工具类，可以获取指定路径下的全部类
        ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
        try {
            String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
                    ClassUtils.convertClassNameToResourcePath(basePackage) + RESOURCE_PATTERN;
            Resource[] resources = resourcePatternResolver.getResources(pattern);
            //MetadataReader 的工厂类
            MetadataReaderFactory readerFactory = new CachingMetadataReaderFactory(resourcePatternResolver);
            for (Resource resource : resources) {
                //用于读取类信息
                MetadataReader reader = readerFactory.getMetadataReader(resource);
                //扫描到的class
                String classname = reader.getClassMetadata().getClassName();
                Class<?> clazz = Class.forName(classname);
                //判断是否有指定主解
                DubboService annotationMetadata = clazz.getAnnotation(DubboService.class);
                if (annotationMetadata != null) {
                    //将注解中的类型值作为key，对应的类作为 value
                    classList.add(annotationMetadata.interfaceClass());
                }
            }
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
            return null;
        }
        return classList;
    }

    /**
     * 根据类名称获取所有的方法
     *
     * @param clazz
     * @return
     */
    public static List<Method> getClassMethod(Class clazz) {
        Method[] clazzMethods = clazz.getDeclaredMethods();
        return Arrays.stream(clazzMethods).collect(Collectors.toList());
    }
}
